﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EtlComm;
using System.Net.Sockets;
using System.Net;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using System.Security.Cryptography;
using EtlContract;
using System.Data.SqlClient;

namespace EtlLog
{
    /// <summary>
    /// 服务端NetLog完成Log信息分发
    /// </summary>
    public class NetLog:ServiceBaseLog,IDisposable
    {
        private string private_key = "BwIAAAAiAABEU1MyAAQAALXh6+TmaNtYku5hqpaOnWnfdZGOZhgTb/sV52M2/6XuDXXA6HbmR18Ghhr9Iv0P9TaUjXS/wG/MOxGV3ZaLwnLJ8gLg4/rwJNtl+k1Ftt4ejj307JvV44ekdYOp7+biL7B372uVwm6+d4zV7rzmJZyWUzjCOD3BPfDRcBptk5GrjzZM22g2WLacPQj2AW7MhR4L+v5vFuoHqQt7JGM/+GZ/4Jt69X3Y16HzdyU3iqxsMZEaw+wHqdJiycvXb3Mecuy1/X3BWVxBzWsauXKepFc3pnv6wi8i9tvM2Yz++SILQtLR20DpC8SdmF/jb1FrvbI425wssHp0bEGR9ZMtoLsH4hF7AJVmOhbq1bIKjkMlcNrJHvROSsMHmsVT8plFFyFeREjgRgjySwAAAI8bVbjFvPdcglWMTXJlQpnkLfpg";
        private DSACryptoServiceProvider rsa = new DSACryptoServiceProvider();
        UdpClient _udpclient = new UdpClient(AddressFamily.InterNetwork);
        log4net.ILog innerLog = log4net.LogManager.GetLogger("App.Logging");

        public NetLog()
        {
            WCFEtlServices wcfEtl = new WCFEtlServices();

            IPEndPoint iep = new IPEndPoint(IPAddress.Parse(wcfEtl.GetMuitlCastAddress()), 7824);
            _udpclient.Connect(iep);
        }

        public override bool WriteLog(string StationID, string TaskID, string loginfo)
        {
            //innerLog.InfoFormat("加油站[{0}] 任务[{1}] {2}", StationID, TaskID, loginfo);
            return base.WriteLog(StationID, TaskID, loginfo);
        }

        public override bool WriteLog(string StationID, string TaskID, string loginfo, LogType logtype)
        {
            if (logtype == LogType.ERROR)
            {
                string strError = string.Format("ERROR:加油站[{0}] 任务[{1}] {2}", StationID, TaskID, loginfo);
                innerLog.InfoFormat(strError);
                WriteDB(StationID, strError);
            }
            return base.WriteLog(StationID, TaskID, loginfo,logtype);
        }

        private void WriteDB(string StationID, string strError)
        {
            try
            {
                using (SqlConnection c = new SqlConnection(ConnectString))
                using (SqlCommand sqlcmd = new SqlCommand())
                {
                    c.Open();
                    sqlcmd.CommandText = string.Format("update OWN_Station_Log set remark = '{0}' where StationID= '{1}'", StationID, strError);
                    sqlcmd.Connection = c;
                    sqlcmd.ExecuteNonQuery();
                }
            }
            catch { }
        }

        public override void FireTaskProcess(string StationID, string TaskID, DispatchProcess dp, string Messages)
        {
            LogData logdata = new LogData()
            {
                StationID = StationID,
                TaskID = TaskID,
                ProcessState = dp,
                Magic = 1978,
                EventTime = DateTime.Now,
                ErrorMessage = Messages
            };

            PorcessLogdata(logdata);
            base.FireTaskProcess(StationID, TaskID, dp, Messages);
        }

        public override void FireTaskProcess(string StationID, string TaskID, DispatchProcess dp, string Messages,LogType logtype)
        {
            LogData logdata = new LogData()
            {
                StationID = StationID,
                TaskID = TaskID,
                ProcessState = dp,
                Magic = 1978,
                EventTime = DateTime.Now,
                ErrorMessage = Messages
            };

            PorcessLogdata(logdata);
            base.FireTaskProcess(StationID, TaskID, dp, Messages,logtype);
        }

        public override void FireTaskProcess(string StationID, string TaskID, DispatchProcess dp, string Messages, int ExtrCount, int LoadCount)
        {
            LogData logdata = new LogData()
            {
                StationID = StationID,
                TaskID = TaskID,
                ProcessState = dp,
                Magic = 1978,
                EventTime = DateTime.Now,
                ErrorMessage = Messages,
                ExtractCount = ExtrCount,
                LoadCount = LoadCount
            };

            PorcessLogdata(logdata);
            base.FireTaskProcess(StationID, TaskID, dp, Messages, ExtrCount, LoadCount);
        }

        private void PorcessLogdata(LogData logdata)
        {
            if (!EtlGlobal.IsBrocast)
                return;
            try
            {
                BinaryFormatter b = new BinaryFormatter();
                MemoryStream ms = new MemoryStream();
                b.Serialize(ms, logdata);
                byte[] buffer = ms.GetBuffer();
                string strBuf = Convert.ToBase64String(buffer);
                DigitalSignature ds = CreateSignature(strBuf);
                ms.Position = 0;
                b.Serialize(ms, ds);
                buffer = ms.GetBuffer();
                _udpclient.Send(buffer, buffer.Length);
            }
            catch (System.Exception ex)
            {
                WriteLog(ex.Message + "\n" + ex.StackTrace+"\n");
            }
            
        }
        /// <summary>
        /// 生成数字签名
        /// </summary>
        /// <param name="strData">待签名的数据</param>
        /// <returns>数字签名</returns>
        private DigitalSignature CreateSignature(string strData)
        {
            DSACryptoServiceProvider dsa = new DSACryptoServiceProvider();
            dsa.ImportCspBlob(Convert.FromBase64String(private_key));
            SHA1Managed sha1 = new SHA1Managed();
            DSASignatureFormatter sigFormatter = new DSASignatureFormatter(dsa);

            byte[] data_Bytes = Encoding.Default.GetBytes(strData);
            byte[] hash_Bytes = sha1.ComputeHash(data_Bytes);
            sigFormatter.SetHashAlgorithm("SHA1");
            byte[] signedHash = sigFormatter.CreateSignature(hash_Bytes);

            DigitalSignature ds = new DigitalSignature();
            ds.data = data_Bytes;
            ds.hashValue = hash_Bytes;
            ds.signature = signedHash;
            return ds;
        }

        #region IDisposable 成员

        public void Dispose()
        {
            _udpclient.Close();
        }

        #endregion
    }
}
